-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at:
--         http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.

-- Description: 升级hpm包
local firmware_client = require 'bios.client'
local ctx = require 'mc.context'
local log = require 'mc.logging'
local vos = require 'utils.vos'
local skynet = require 'skynet'
local mdb = require 'mc.mdb'

local firmware_upgrade = {}

local SYSTEM_ID<const> = 1

--查询升级进度
local function wait_upgrade_finish(task_id)
    local path = '/bmc/kepler/UpdateService/TaskService/Tasks/' .. task_id
    local intf = 'bmc.kepler.TaskService.Task'
    local obj = mdb.get_object(bus, path, intf)
    local query_count = 0
    -- 5分钟左右
    while query_count < 300 do
        log:debug('upgrade bios: loop=%d, task State=%s, Progress=%d', query_count, obj.State, obj.Progress)
        if obj.State == 'Completed' and obj.Progress == 100 then
            return true
        end
        query_count = query_count + 1
        skynet.sleep(100)
    end
    return false
end

-- 通过firware_mgmt升级bios.hpm
function firmware_upgrade:upgrade_hpm_by_firmware(path)
    if not path or not vos.get_file_accessible(path) then
        log:error("[bios]upgrade hpm by firmware: path no accessible.")
        return false
    end

    local ok, response = firmware_client:
            PUpdateServiceUpdateServiceStartUpgrade(ctx.new(), SYSTEM_ID, path)
    if not ok then
        log:error('[bios]upgrade hpm by firmware: call firmware_mgnt fail.')
        return false
    end

    log:notice('[bios]upgrade hpm by firmware: call firmware_mgnt success.')
    ok = wait_upgrade_finish(response.TaskId)
    if not ok then
        log:error('[bios]upgrade hpm by firmware: upgrade fail.')
        return false
    end

    log:notice('[bios]upgrade hpm by firmware: upgrade success.')
    return true
end

-- 升级bios.hpm
function firmware_upgrade.upgrade_hpm(path, retry_times)
     for i = 1, retry_times do
        local res = firmware_upgrade.upgrade_hpm_by_firmware(path)
        if res then
            log:notice('[bios]upgrade_hpm: upgrade success.')
            return true
        end
        log:error('[bios]upgrade_hpm: retry %d times.', i)
    end
    return false
end

function firmware_upgrade.get_package_info(file_path)
    local ok, package_info
    for _ = 1, 10 do
        ok, package_info = pcall(function ()
            return firmware_client:UpdateServiceUpdateServiceParseFirmwarePackage(ctx.new(), file_path)
        end)
        if ok and package_info then
            break
        end
    end
    if not ok then
        log:error('[bios] parse bios package failed, error:%s', package_info)
        return
    end
    if not package_info or package_info.FirmwareType ~= 'Bios' then
        log:error('[bios] hpm is not bios :%s', package_info.FirmwareType)
        return
    end
    return package_info.FirmwareDirectory
end

return firmware_upgrade